/**	@file Expr.h
 * 	@brief Front-end of library = An interface for work with expressions. */
#ifndef Expr_majdo_
#define Expr_majdo_
#include <string>
namespace sympycpp {
typedef bool Sign;
class Ex;
class Sym;
/**	@class Expr
 * 	@brief Encapsulation of pointer arithmetic of classes taht represent expressions. 
 * 	This class is interface for normal work. Usual user need be able use only this class.*/	
class Expr{
	///	@brief Encapsulated expression.
	Ex * e_;
public:
	///	@brief Redefinition of allocationPolicy
	///	@see sympycpp::allocationPolicy
	typedef enum { 
		STEALING 
	}  allocationPolicy;	
	/**	@brief Construction of numbers. */
	Expr(const int);
	/**	@brief Construction of numbers. */
	Expr(const double);
	/**	@brief Construction of variables. */
	explicit Expr(const std::string &);
	/**	@brief Construction of variables. */
	explicit Expr(const char *);
	/**	@brief Construction of long numbers. 
	 * 	@param f is only flag, that makes this constructor differnt from the constructor of variables.
	 * 	@param n is the textual form of integer or rational number*/
	Expr(const int , const char *);
	///	@brief Standard copy constructor
	Expr(const Expr &);
	/**	@brief Special exploiting constructor. (encapsulation)
	 * 	Thsi constructor exploits memory from the input parameter.
	 * 	@see allocationPolicy*/	
	Expr(Ex * &, const allocationPolicy);
	///	@brief Construction of expression. (encapsulation)
	Expr(const Ex *);
	virtual ~Expr();
	///	@brief Change sign.
	void sign(const Sign &);
	///	@brief Actual sign.
	Sign sign() const;
	///	@brief Transformation to textual form as mathematical expression.
	std::string str() const; 
	///	@brief Transfromation to textual form as n-ry tree.
	std::string tree() const; 
	/**	@brief Substitution.
	 *	@param from is replaced expression
	 *	@param to is repalcing expression */
	void sub(const Expr & from, const Expr & to);
	/**	@brief Expansion.
	 * 	@param level is the number of nested multiplications, that will be expanded*/
	bool expansion(const int level = -1); 
	/**	@brief Taylor series.
	 * 	This function returns Taylor series of the stored expression.
	 * 	@param x is variable. The differntiation are made with respect to this variable.
	 * 	@param a is point. The series is in this point.
	 * 	@param n is maximal derivation.*/
	Expr taylorSeries(const Expr & x, const Expr & a, const int n) const;
	///	@brief Differentaiation with respect to <i>x</i>.
	Expr &  diff(const Expr &);
	/**	@brief Inner structure.	
	 * 	This function returns copy of the encapsulated structure that represents expressions.
	 * 	@warning This function returns alocated memory. The user is responsible for release it.*/
	Ex * innerCopy() const;
	///	@brief Unary minus.
	Expr operator-()const;
	///	@brief Assignment.
	const Expr & operator=(const Expr & x);
	/**	@brief Set the count of printed digits in real numbers.
	 *	@warning This function provides funtionality of external library. 
	 *	Consequently, the effect is not guaranteed.*/
	static void setPrecision(const int);
	/**	@brief Information about the count of printed digits in real numbers.
	 *	@warning This function provides funtionality of external library. 
	 *	Consequently, the effect is not guaranteed.*/
	static int getPrecision();
	friend class Operations;
	friend class Utilities;
	friend class Fx;
};
/**	@brief Addition.
 * 	Operator+ is a way how to make addition of two expressions {Expr}. */
Expr operator+(const Expr & L, const Expr & R); 
/**	@brief Subtraction.
 * 	Operator- is a way how to make subtraction of two expressions {Expr}. */
Expr operator-(const Expr & L, const Expr & R);
/**	@brief Multiplication.
 * 	Operator* is a way how to make multiplication of two expressions {Expr}. */
Expr operator*(const Expr & L, const Expr & R);
/**	@brief Construction of powers from Expr.
 * 	Operator ^ has bad priority. ^ is available, but using is uneasy and misleadig.
 * 	This function is an alternativ to this operator.
 * 	@see operator^(const Expr &, const Expr &);	  
 */
Expr Power(const Expr & base, const Expr & exponent);
/**	@brief Construction of powers.
 * 	This operator makes basic simplification and creates new expression from incoming expressions.
 * 	@warning Operator^ has bad priority and using is uneasy and misleading. Use Power(const Expr &, const Expr &).	
 * 	@see Power --> alternative function
 *	@param base is base of the power.
 *	@param exponent is exponent of the power.
 *	@return base to the power of exponent
*/
Expr operator^(const Expr & base, const Expr & exponent);
/**	@brief Division.
 * 	Operator/ is a way how to make division {Expr}. */
Expr operator/(const Expr & L, const Expr & R);
///	@brief Constant Pi
extern const Expr pi;
}
#endif
